﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace Aden.Util.queue
{
    public class TaskQueue
    {
        private static List<SiteSQLs> tasks = new List<SiteSQLs>();

        public void Enqueue(string site, string guid, string conn, string sql)
        {
            try
            {
                if (String.IsNullOrWhiteSpace(site) || string.IsNullOrWhiteSpace(guid))
                    throw new Exception("Can't blank");
                
                SQL tmpsql = new SQL
                {
                    id = guid,
                    connection = conn,
                    command = sql,
                };

                string sLock = "aden";
                lock (sLock)
                {
                    //s.AppendFormat(" --- {0}", seq++);
                    if (tasks.Any(q => q.Site == site))
                    {
                        tasks.First(q => q.Site == site).SQLs.Enqueue(tmpsql);
                        return;
                    }

                    ConcurrentQueue<SQL> queue = new ConcurrentQueue<SQL>();
                    queue.Enqueue(tmpsql);

                    tasks.Add(new SiteSQLs
                    {
                        Site = site,
                        SQLs = queue
                    });
                }
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        public void Dequeue(string site, Action<string, string> process)
        {
            Task.Factory.StartNew(() =>
            {
                string sLock = site;
                //process("start");
                lock (sLock)
                {
                    //process("Get data");
                    if (!tasks.Any(q => q.Site == site)) return;

                    ConcurrentQueue<SQL> sqls = tasks.First(q => q.Site == site).SQLs;
                    while (sqls.Count > 0)
                    {
                        //System.Threading.Thread.Sleep(1000);
                        SQL sql = null;
                        if (!sqls.TryDequeue(out sql)) continue;
                        if (sql == null || string.IsNullOrWhiteSpace(sql.command)) continue;

                        string str = "";
                        try
                        {
                            process(sql.connection,sql.command);
                        }
                        catch (Exception e)
                        {
                            str = e.Message;
                        }
                        (new MSMQ()).SendMessage(sql.id, str);
                    }

                    //process("Completed");
                }
            }
            );
        }
    }

    class SiteSQLs
    {
        public string Site;
        public ConcurrentQueue<SQL> SQLs;
    }

    class SQL
    {
        public string id;
        public string connection;
        public string command;
    }
}
